package com.fingard.dsp.bank.directbank.fuiou01;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.fingard.constant.Format;
import com.fingard.crypto.DigestHelper;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.IRealTime;
import com.fingard.dsp.bank.reqrespobj.single.ReqQrySingle;
import com.fingard.dsp.bank.reqrespobj.single.ReqSingle;
import com.fingard.dsp.bank.reqrespobj.single.RetAtsSingle;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

/**
 *  富友代收付平台单笔实时代扣
 */
public class FUIOU01RealTime extends FUIOU01Base implements IRealTime {
	/**
	 * 单笔实时代扣交易提交
	 */
	@Override
	public RetAtsSingle d_9108_RealTimeRec(ReqSingle p_req9108)	throws Exception {
		RetAtsSingle retAts = new RetAtsSingle(p_req9108.reqHeader);
		RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
		
		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_req9108.singleDetail.recAct, "");
			if (actItem == null) {
				tmpRetDetail.respCode = "0";
				tmpRetDetail.respInfo = "未找到该账号("+p_req9108.singleDetail.recAct+")对应的商户信息";
				tmpRetDetail.reqSeqID = p_req9108.singleDetail.askNumber;
				tmpRetDetail.transState = PaymentState.FAIL_Payment;
				tmpRetDetail.payInfoCode = "E9981";
				
				retAts.writeRetDetail(tmpRetDetail);
				
				return retAts;
			}
			
			FUIOU01Header bankHeader = new FUIOU01Header();
			bankHeader.reqtype = "sincomeforreq";
			
			Map<String,String> postParams = new HashMap<String,String>();
			postParams.put("merid", actItem.merchantId);
			postParams.put("reqtype", bankHeader.reqtype);

			XmlTextWriter xmlWriter = new XmlTextWriter();
			xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"" + getCharset()+"\" standalone=\"yes\"?>");
			xmlWriter.writeStartElement("incomeforreq");
			xmlWriter.writeElementString("ver", "1.00");
			xmlWriter.writeElementString("merdt", Format.Date8Format.format(new Date()));
			xmlWriter.writeElementString("orderno", p_req9108.singleDetail.askNumber);
			xmlWriter.writeElementString("bankno", getBankConfig().getMapValueByKey("bankMapping", p_req9108.singleDetail.payBankCode));
			xmlWriter.writeElementString("accntno", p_req9108.singleDetail.payAct);
			xmlWriter.writeElementString("accntnm", p_req9108.singleDetail.payName);
			xmlWriter.writeElementString("amt", StringHelper.amountMultiply100(p_req9108.singleDetail.payAmount));
			xmlWriter.writeElementString("memo", p_req9108.singleDetail.memo);
			xmlWriter.writeElementString("mobile", p_req9108.singleDetail.cellPhone);
			xmlWriter.writeElementString("certtp", convertCertTypeToBank(p_req9108.singleDetail.certType));
			xmlWriter.writeElementString("certno", p_req9108.singleDetail.certNum);
			xmlWriter.writeEndElement();
			xmlWriter.writeEndDocument();
				
			String reqStr = actItem.merchantId + "|" + actItem.saltKey + "|" + bankHeader.reqtype + "|" + xmlWriter.toXmlString();
			String mac = DigestHelper.cryptoMD5RetHexStr(reqStr.getBytes(getCharset()));
			
			postParams.put("xml", xmlWriter.toXmlString());
			postParams.put("mac", mac);
			
			String[] tmpStrRet = sendToBank("generalPay", postParams);
			
			if (tmpStrRet[0].length() == 0) {
				StringBuilder tmpSbMsg = new StringBuilder();
				XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
				if (tmpBkReader != null) {
					String tmpRespCode = tmpBkReader.getFirstText("/incomeforrsp/ret");
					String tmpRespInfo = tmpBkReader.getFirstText("/incomeforrsp/memo");
					if (tmpRespCode.equals("000000")) {
						tmpRetDetail.respCode = "0";
						tmpRetDetail.respInfo = tmpRespInfo;
						tmpRetDetail.reqSeqID = p_req9108.singleDetail.askNumber;
						tmpRetDetail.transAmt = p_req9108.singleDetail.payAmount;
						tmpRetDetail.transState = tmpRespCode;
						tmpRetDetail.payInfoCode = tmpRetDetail.transState;
					}else {
						tmpRetDetail.respCode = "-1";
						tmpRetDetail.respInfo = tmpRespInfo;
					}
				}else {
					tmpRetDetail.respCode = "-1";
					tmpRetDetail.respInfo = tmpSbMsg.toString();
				}
			} else if (tmpStrRet[0].equals(ConnState.FAIL) || tmpStrRet[0].equals(FailCode.E9981)) {
				tmpRetDetail.respCode = "0";
				tmpRetDetail.respInfo = tmpStrRet[1];
				tmpRetDetail.reqSeqID = p_req9108.singleDetail.askNumber;
				tmpRetDetail.transState = PaymentState.FAIL;
				tmpRetDetail.payInfoCode = tmpStrRet[0];
			} else {
				tmpRetDetail.respCode = "-1";
				tmpRetDetail.respInfo = tmpStrRet[1];
			}
		} catch (Exception e) {
			tmpRetDetail.respCode = "-1";
			tmpRetDetail.respInfo = e.toString();
			e.printStackTrace();
		}
		
		if (tmpRetDetail.respCode.equals("-1") && StringHelper.isNullOrEmpty(tmpRetDetail.reqSeqID)) {
			tmpRetDetail.reqSeqID = p_req9108.singleDetail.askNumber;
		}
		
		retAts.writeRetDetail(tmpRetDetail);
		return retAts;
	}

	/**
	 * 单笔实时代扣状态查询
	 */
	@Override
	public RetAtsSingle d_9144_QryRealTimeRec(ReqQrySingle p_req9144) throws Exception {
		RetAtsSingle retAts = new RetAtsSingle(p_req9144.reqHeader);
		RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
		
		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_req9144.recAct, "");
			if (actItem == null) {
				tmpRetDetail.respCode = "-1";
				tmpRetDetail.respInfo = "未找到账号" + p_req9144.recAct + "对应的商户配置节点";
				tmpRetDetail.reqSeqID = p_req9144.askNumber;
				tmpRetDetail.transState = PaymentState.FAIL;
				tmpRetDetail.payInfoCode = FailCode.E9981;
				
				retAts.writeRetDetail(tmpRetDetail);
				return retAts;
			}
			
			FUIOU01Header bankHeader = new FUIOU01Header();
			bankHeader.reqtype = "qrytransreq";
			
			Map<String,String> postParams = new HashMap<String,String>();
			postParams.put("merid", actItem.merchantId);
			postParams.put("reqtype", bankHeader.reqtype);

			XmlTextWriter xmlWriter = new XmlTextWriter();
			xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"" + getCharset()+"\" standalone=\"yes\"?>");
			xmlWriter.writeStartElement("qrytransreq");
			xmlWriter.writeElementString("ver", "1.00");
			xmlWriter.writeElementString("busicd", "AC01");
			xmlWriter.writeElementString("orderno", p_req9144.askNumber);
			String transDate = Format.Date8Format.format(p_req9144.getBgnDateTime());
			xmlWriter.writeElementString("startdt", transDate);
			xmlWriter.writeElementString("enddt", transDate);
			xmlWriter.writeEndElement();
			xmlWriter.writeEndDocument();
				
			String reqStr = actItem.merchantId + "|" + actItem.saltKey + "|" + bankHeader.reqtype + "|" + xmlWriter.toXmlString();
			String mac = DigestHelper.cryptoMD5RetHexStr(reqStr.getBytes(getCharset()));
			
			postParams.put("xml", xmlWriter.toXmlString());
			postParams.put("mac", mac);
			
			String[] tmpStrRet = sendToBank("generalPay", postParams);
			
			if (tmpStrRet[0].length() == 0) {
				StringBuilder tmpSbMsg = new StringBuilder();
				XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
				if (tmpBkReader != null) {
					String tmpRespCode = tmpBkReader.getFirstText("/qrytransrsp/ret");
					String tmpRespInfo = tmpBkReader.getFirstText("/qrytransrsp/memo");
					if (tmpRespCode.equals("000000")) {
						tmpRetDetail.respCode = "0";
						tmpRetDetail.respInfo = tmpRespInfo;
						tmpRetDetail.reqSeqID = p_req9144.askNumber;
						tmpRetDetail.transAmt = StringHelper.amountDivide100(tmpBkReader.getFirstText("/qrytransrsp/trans/amt"));
						tmpRetDetail.transState = tmpRespCode + "+" + tmpBkReader.getFirstText("/qrytransrsp/trans/state");
						tmpRetDetail.payInfoCode = tmpRespCode;
					}else {
						tmpRetDetail.respCode = "-1";
						tmpRetDetail.respInfo = tmpRespInfo;
					}
				}else {
					tmpRetDetail.respCode = "-1";
					tmpRetDetail.respInfo = tmpSbMsg.toString();
				}
			} else {
				tmpRetDetail.respCode = "-1";
				tmpRetDetail.respInfo = tmpStrRet[1];
			}
		} catch (Exception e) {
			tmpRetDetail.respCode = "-1";
			tmpRetDetail.respInfo = e.getMessage();
			e.printStackTrace();
		}
		
		retAts.writeRetDetail(tmpRetDetail);
		return retAts;
	}
}
